import os
import sys, json
from datetime import datetime, date
# import pprint
from PyQt5.Qt import *
# from PyQt5.uic import loadUi
# from msg import Msg
import requests

from logger import logger
from main_ui import Ui_MainWindow
from mk_document import mk_document

history_file = 'history.json'


class Window(Ui_MainWindow, QMainWindow):
    def __init__(self):
        super().__init__()
        # self.set_ui()
        self.setupUi(self)
        self.move(450, 200)
        self.info = {}
        self.set_ui()
        # self.history_file = 'history.json'

    def textCao(self):
        '''
        监测url输入框
        :return:
        '''
        if self.lineEdit.text().replace(' ', '') != '':
            self.pushButton.setEnabled(True)
        else:
            self.pushButton.setEnabled(False)
        self.pushButton_4.setEnabled(False)
        self.pushButton_5.setEnabled(False)

    def textCao1(self):
        '''
        监测url输入框
        :return:
        '''
        self.pushButton_5.setEnabled(False)

    def set_ui(self):
        # loadUi('./ui/main.ui', self)
        # QPushButton
        # 提前禁用发送按钮
        self.pushButton.setEnabled(False)
        self.lineEdit.textChanged.connect(self.textCao)
        self.textEdit_3.textChanged.connect(self.textCao1)
        # self.lineEdit.setPlaceholderText('请输入请求地址')
        # 设置占位文本
        # self.textEdit.setPlaceholderText('json类型请求数据')

        # 发送按钮
        self.pushButton.clicked.connect(self.send_msg)
        # 添加消息头按钮
        self.pushButton_2.clicked.connect(self.addTable)
        # 删除一行
        self.pushButton_3.clicked.connect(self.delTable)
        # 情况显示框
        self.pushButton_4.clicked.connect(self.copyResult)
        self.pushButton_4.setEnabled(False)
        # 复制文档
        self.pushButton_5.clicked.connect(self.copyBoard)
        self.pushButton_5.setEnabled(False)
        # 刷新历史记录
        self.pushButton_6.clicked.connect(self.treeMK)
        # 重置输入内容
        self.pushButton_7.clicked.connect(self.resetInput)
        # 清空历史记录
        self.pushButton_8.clicked.connect(self.clearHistory)
        # 删除单个选中的历史记录
        self.pushButton_9.clicked.connect(self.delHistory)
        # 消息头表格
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setHorizontalHeaderLabels(['key', 'value'])
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 响应结果框
        self.textEdit_2.setReadOnly(True)
        # self.textEdit_2.currentCharFormat()
        # 设置历史记录的初始化
        self.treeMK()
        # 设置树状图的点击事件
        self.tree_1.doubleClicked.connect(self.fill_history)

    def treeMK(self):
        '''
        历史记录的树状图显示
        :return:
        '''
        self.tree_1.clear()

        if not os.path.exists(history_file):
            json_data = {}
            json_data[str(date.today())] = []
            # json_data[str(date.today())].insert(0, data)
            with open(history_file, 'w', encoding='utf-8') as f:
                # f.write(json.dumps(json_data))
                f.write(json.dumps({}))
            # print('生成文件成功')
            return
        with open(history_file, 'r', encoding='utf-8') as f:
            try:
                json_data = json.loads(f.read())
            except:
                logger.error('格式化显示历史记录失败1', exc_info=True)
                return
        new_json_data = sorted(json_data.items(), key=lambda item: item[0], reverse=True)
        for v in new_json_data:
            # (date,data)
            root = QTreeWidgetItem(self.tree_1)
            root.setText(0, v[0])
            for v2 in v[1]:
                child = QTreeWidgetItem(root)
                # child.setText(0, k2)
                child.setText(0, v2.get('method') + '  ' + v2.get('url'))
                child.setToolTip(0, v2.get('url'))

    def save_history(self, des, method, head, req_data, url):

        with open(history_file, 'r', encoding='utf-8') as f:
            try:
                json_data = json.loads(f.read())
            except:
                logger.error('格式化显示历史记录失败2', exc_info=True)
                json_data = {}
        today_data = json_data.get(str(date.today()), None)

        data = {
            "method": method.upper(),
            "head": "%s" % head,
            "req_data": "%s" % req_data,
            "url": "%s" % url,
            "des": "%s" % des
        }
        if today_data:
            json_data[str(date.today())].insert(0, data)
            with open(history_file, 'w', encoding='utf-8') as f:
                f.write(json.dumps(json_data))
        else:
            json_data[str(date.today())] = []
            json_data[str(date.today())].insert(0, data)
            with open(history_file, 'w', encoding='utf-8') as f:
                f.write(json.dumps(json_data))

    def send_msg(self):
        """
        点击按钮事件
        :return:
        """
        # self.info = {}
        # a = self.tableView.currentIndex().data()
        # print(a)
        # 请求方式
        postMethod = self.comboBox.currentText()
        # 请求地址
        self.info['method'] = postMethod
        # str.startswith()
        url = self.lineEdit.text().replace(' ', '')
        if url.startswith('https://') or url.startswith('http://'):
            pass
        else:
            url = 'http://' + url
        # print(url)
        self.info['url'] = url
        try:
            self.info['des'] = self.textEdit_3.toPlainText()
            des = self.textEdit_3.toPlainText()
            # print('请求信息：', self.info)
        except:
            self.info['des'] = ''
            des = ''
            logger.error('获取描述信息error', exc_info=True)
        # 获取请求参数
        data = {}
        try:
            # data = self.textEdit.toPlainText().replace(' ', '')
            data = self.textEdit.toPlainText()
            if data != '':
                self.info['req_data'] = data
                data = eval(data)
            else:
                self.info['req_data'] = ''
        except:
            # print('error_1:', e)
            logger.error('获取请求参数失败error', exc_info=True)
        headers = {}
        rows = self.tableWidget.rowCount()
        try:
            for i in range(rows):
                d = []
                for j in range(2):
                    d.append(self.tableWidget.item(i, j).text())
                headers[d[0]] = d[1]
            self.info['req_head'] = headers
            # print('请求头信息：', headers)
        except:
            # pass
            # print('error_2:', e)
            logger.error('获取请求头参数失败error', exc_info=True)

        head = '''\r-----------请求参数----------
        \r{0} {1}'''.format(postMethod, url)
        head += "\rDate:{}".format(datetime.now())
        for k, v in headers.items():
            if k.replace(' ', '') != '':
                head += "\r{}:{}".format(k, v)
        head += "\n\r{}".format(data)

        self.textEdit_2.setText(head)

        res = ''
        res_text = head + '\n\n\r----------得到响应----------'
        res_text += "\rDate:{}".format(datetime.now())
        # 设置接口返回的content-type类型
        self.info['res_data_type'] = 'text'
        try:
            # print('请求类型：', postMethod)

            if postMethod == 'GET':
                if len(headers):
                    res = requests.request(postMethod, url, json=data, headers=headers)
                else:
                    res = requests.request(postMethod, url, json=data)
            elif postMethod == 'POST':
                # print('json:', data)
                if len(headers):
                    res = requests.request(postMethod, url, json=data, headers=headers)
                else:
                    res = requests.request(postMethod, url, json=data)

            # print('返回头部信息:', res.headers.get('Content-Type'), type(res.headers.get('Content-Type')))

            self.info['res_data_type'] = 'json' if res.headers.get('Content-Type') == 'application/json' else res.headers.get('Content-Type')

            res_text += '\rstatus_code:{}'.format(res.status_code)
            res_text += '\rDate:{}'.format(res.headers.get('Date'))
            res_text += '\rContent-Type:{}'.format(res.headers.get('Content-Type'))
            res_text += '\rContent-Length:{}'.format(res.headers.get('Content-Length'))
            res_text += '\rConnection:{}'.format(res.headers.get('Connection'))

        except Exception as e:
            # print('error_3', e)
            res_text += "\rERROR:{}".format(e)
        self.save_history(des, postMethod, headers, data, url)
        try:
            res_data = res.content.decode('utf-8')
        except:
            res_data = res

        self.pushButton_5.setEnabled(True)
        if self.info['res_data_type'] == 'json':
            res_data = json.loads(res_data)
            self.pushButton_4.setEnabled(True)
        else:
            # print('error_4', e)
            self.pushButton_5.setEnabled(False)
            self.pushButton_4.setEnabled(False)
        self.info['res_data'] = res_data
        res_text += '\n\r{}'.format(res_data)

        self.textEdit_2.setText(res_text)
        self.treeMK()

    def addTable(self):
        '''
        增加表格行
        :return:
        '''
        row_num = self.tableWidget.rowCount()  # 获取当前的列数
        self.tableWidget.setRowCount(row_num + 1)

    def delTable(self):
        '''
        删除表格行
        :return:
        '''
        r = self.tableWidget.currentRow()
        # print('当前选中行:', r)
        if r == -1:
            r = self.tableWidget.rowCount() - 1
        # print(r)
        self.tableWidget.removeRow(r)

    def copyResult(self):
        try:
            # print(self.info.get('res_data'))
            docu = self.info.get('res_data')
            res_data = json.dumps(docu, indent=4, ensure_ascii=False, separators=(',', ': '))
            # print(res_data)
            clipboard = QApplication.clipboard()
            clipboard.setText(res_data)
            # self.pushButton_4.setEnabled(False)
        except:
            logger.error('复制结果失败error', exc_info=True)
            # print(e)

    def copyBoard(self):
        '''复制生成的文档到剪切板'''
        docu = mk_document(self.info)
        clipboard = QApplication.clipboard()
        clipboard.setText(docu)
        # self.pushButton_5.setEnabled(False)
        # self.textEdit_3.setEnabled(True)
        # self.textEdit_3.clear()

    def fill_history(self, index):
        '''
        使用历史记录
        :return:
        '''
        # print('123:',index, type(index))
        # print((dir(index)))
        with open(history_file, 'r', encoding='utf-8') as f:
            json_data = json.loads(f.read())

        # item = self.tree_1.currentItem()
        if index.parent().row() == -1:
            # print('根目录')
            pass
        else:
            row = index.row()
            # print('树：', dir(index))
            # print('树：', index.data())
            root_name = index.parent().data()
            data = json_data.get(root_name)
            current_data = data[row]
            h_url = current_data.get('url')
            h_head = current_data.get('head')
            h_method = current_data.get('method')
            h_req_data = current_data.get('req_data')
            h_des = current_data.get('des')
            self.lineEdit.setText(h_url)
            self.comboBox.setCurrentText(h_method)
            self.header_control(h_head)
            self.textEdit.setText(h_req_data)
            self.textEdit_3.setText(h_des)
            self.textEdit_2.clear()
            # QTextEdit

    def header_control(self, headers):
        '''
        历史记录填充，进行head的内容格式化填入
        :param headers:
        :return:
        '''
        self.tableWidget.clear()
        headers = eval(headers)

        self.tableWidget.setColumnCount(2)
        self.tableWidget.setHorizontalHeaderLabels(['key', 'value'])
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

        rows = list(headers.keys())
        if '' in rows:
            rows.remove('')
        # print(rows)
        self.tableWidget.setRowCount(len(rows))
        c1 = 0
        c2 = 0
        for k, v in headers.items():
            k = k.replace(' ', '')
            # print('---{}---'.format(k))
            if k == '':
                continue
                # print(111)
                # break
            model = QTableWidgetItem()
            # model.setColumnCount(3)
            model.setText(k)
            self.tableWidget.setItem(c1, c2, model)
            c2 += 1

            model = QTableWidgetItem()
            # model.setColumnCount(3)
            model.setText(v)
            self.tableWidget.setItem(c1, c2, model)
            c2 = 0
            c1 += 1

    def resetInput(self):
        self.lineEdit.clear()
        self.comboBox.setCurrentText('GET')
        # QTableWidget
        self.tableWidget.clear()
        self.tableWidget.setRowCount(0)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setHorizontalHeaderLabels(['key', 'value'])
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.textEdit.clear()
        self.textEdit_2.clear()
        # self.textEdit_3.setEnabled(True)
        self.textEdit_3.clear()

    def clearHistory(self):
        with open(history_file, 'w') as f:
            f.write(json.dumps({}))

        self.treeMK()

    def delHistory(self):
        item = self.tree_1.currentItem()
        cur_item = self.tree_1.indexFromItem(item)
        # print(dir(cur_item), cur_item.row())
        if cur_item.row() == -1:
            return
        parent_item = cur_item.parent()

        with open(history_file, 'r', encoding='utf-8') as f:
            json_data = json.loads(f.read())
        # 节点行数为-1，代表是根节点
        if parent_item.row() == -1:
            # print()
            root_name = cur_item.data()
            # print('选中的是根目录：', root_name)
            json_data.pop(root_name)
        else:
            root_name = parent_item.data()
            json_data[root_name].pop(cur_item.row())

        with open(history_file, 'w', encoding='utf-8') as f:
            f.write(json.dumps(json_data))
        self.treeMK()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    # print(window.lineEdit.text())
    window.show()
    sys.exit(app.exec_())
